package cn.javabb.admin.controller;

import cn.javabb.common.model.ResponseModel;
import cn.javabb.core.base.BaseController;
import cn.javabb.core.entity.sys.MenuDO;
import cn.javabb.core.model.LoginType;
import cn.javabb.core.service.sys.MenuService;
import cn.javabb.core.service.sys.UserService;
import cn.javabb.core.shiro.UserToken;
import cn.javabb.core.util.ShiroUtil;
import cn.javabb.log.action.UserAction;
import cn.javabb.log.annotation.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * MainController
 */
@Slf4j
@Controller
@RequestMapping("/admin")
public class MainController extends BaseController {
	@Autowired
	private MenuService menuService;
	@Autowired
	private UserService userService;
	/**
	 * 主页
	 */
	@GetMapping("/")
	public String index(Model model) {
		if(null == ShiroUtil.getLoginUser()){
			return "login";
		}
		List<MenuDO> menus = menuService.listMenuByUserId(ShiroUtil.getLoginUser().getId());
		List<Map<String, Object>> menuTree = getMenuTree(menus, 0);
		model.addAttribute("menus", menuTree);
		model.addAttribute("currentUser", ShiroUtil.getLoginUser());
		return "admin/index";
	}

	/**
	 * 登录页
	 */
	@GetMapping("/login")
	public String login() {
		if (ShiroUtil.getLoginUser() != null) {
			return "redirect:admin";
		}
		return "login";
	}

	/**
	 * 后台登录
	 */
	@ResponseBody
	@PostMapping("/login")
	@Log(name = "用戶登陸",key = UserAction.ADMIN_USER_LOGIN,action = UserAction.class)
	public Object doLogin(String username, String password, String code, HttpServletRequest request) {
		if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) {
			return ResponseModel.Failure("账号密码不能为空");
		}
		log.info("准备登陆用户  =>  {}", username);
		/*
		 * if (!CaptchaUtil.ver(code, request)) { CaptchaUtil.clear(request); return
		 * ResponseModel.Failure("验证码不正确"); }
		 */
		UserToken token = new UserToken(username, password, LoginType.USER.getDesc());
		// 获取当前的Subject
		Subject currentUser = SecurityUtils.getSubject();
		try {
			log.info("对用户[" + username + "]进行登录验证..验证开始");
			currentUser.login(token);
			log.info("对用户[" + username + "]进行登录验证..验证通过");
		} catch (IncorrectCredentialsException ice) {
			return ResponseModel.Failure("密码错误");
		} catch (UnknownAccountException uae) {
			return ResponseModel.Failure("账号不存在");
		} catch (LockedAccountException e) {
			return ResponseModel.Failure("账号被锁定");
		} catch (ExcessiveAttemptsException eae) {
			return ResponseModel.Failure("操作频繁，请稍后再试");
		}
		// 验证是否登录成功
		if (currentUser.isAuthenticated()) {
			log.info("用户[" + username + "]登录认证通过");
			userService.updateUserLastLoginTime(getLoginUser().getId());
			return ResponseModel.Success("登录成功");
			// return "redirect:/index";
		} else {
			token.clear();
			//return "redirect:/login";
			return ResponseModel.Failure("登陆失败");
		}

	}

	/**
	 * 图形验证码，用assets开头可以排除shiro拦截
	 */
	/*
	 * @RequestMapping("/assets/captcha") public void captcha(HttpServletRequest
	 * request, HttpServletResponse response) { try { CaptchaUtil.out(4, request,
	 * response); } catch (IOException e) { e.printStackTrace(); } }
	 */

	/**
	 * iframe页
	 */
	@RequestMapping("/iframe")
	public String error(String url, Model model) {
		model.addAttribute("url", url);
		return "tpl/iframe.html";
	}

	/**
	 * 错误页
	 */
	@RequestMapping("/error")
	public String error(String code) {
		if ("403".equals(code)) {
			return "error/403";
		}
		return "error/404";
	}

	public String getErrorPath() {
		return "/error";
	}

	/**
	 * 递归转化树形菜单
	 */
	private List<Map<String, Object>> getMenuTree(List<MenuDO> menus, Integer parentId) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		for (int i = 0; i < menus.size(); i++) {
			MenuDO temp = menus.get(i);
			if (temp.getType() == 1 && parentId == temp.getParentId()) {
				Map<String, Object> map = new HashMap<>();
				map.put("menuName", temp.getMenuName());
				map.put("menuIcon", temp.getIcon());
				map.put("menuUrl", StringUtils.isBlank(temp.getUrl()) ? "javascript:;" : temp.getUrl());
				map.put("subMenus", getMenuTree(menus, menus.get(i).getId()));
				list.add(map);
			}
		}
		return list;
	}
	@GetMapping("/logout")
	public String logout(RedirectAttributes redirectAttributes) {
		//使用权限管理工具进行用户的退出，跳出登录，给出提示信息
		SecurityUtils.getSubject().logout();
		//
		//redirectAttributes.addFlashAttribute("message", "您已安全退出");
		return "redirect:/login";
	}
}
